package com.zhy.generator.codegen.mybatis;

import com.zhy.generator.codegen.api.GeneratedJavaFile;
import com.zhy.generator.codegen.api.GeneratedXmlFile;
import com.zhy.generator.codegen.api.IntrospectedTable;
import com.zhy.generator.codegen.api.ProgressCallback;
import com.zhy.generator.codegen.dom.java.CompilationUnit;
import com.zhy.generator.codegen.dom.xml.Document;
import com.zhy.generator.codegen.mybatis.javaconstant.JavaConstantGenerator;
import com.zhy.generator.codegen.mybatis.javacontroller.JavaControllerGenerator;
import com.zhy.generator.codegen.mybatis.javahelper.JavaHelperGenerator;
import com.zhy.generator.codegen.mybatis.javamapper.JavaMapperGenerator;
import com.zhy.generator.codegen.mybatis.javapo.JavaPojoGenerator;
import com.zhy.generator.codegen.mybatis.javarequest.JavaRequestGenerator;
import com.zhy.generator.codegen.mybatis.javaservice.JavaServiceGenerator;
import com.zhy.generator.codegen.mybatis.javavo.JavaVoGenerator;
import com.zhy.generator.codegen.mybatis.xmlmapper.XMLMapperGenerator;
import com.zhy.generator.config.ConfigurationConstant;

import java.util.ArrayList;
import java.util.List;

/**
 * @author 源
 */
public class IntrospectedTableZHYImpl extends IntrospectedTable {

    protected List<AbstractJavaGenerator> javaPojoGenerators;

    protected List<AbstractJavaGenerator> javaMapperGenerators;

    protected List<AbstractJavaGenerator> javaServiceGenerators;

    protected List<AbstractJavaGenerator> javaVoGenerators;

    protected List<AbstractJavaGenerator> javaRequestGenerators;

    protected List<AbstractJavaGenerator> javaHelperGenerators;

    protected List<AbstractJavaGenerator> javaControllerGenerators;

    protected List<AbstractJavaGenerator> javaConstantGenerators;

    protected AbstractXmlGenerator xmlMapperGenerator;

    public IntrospectedTableZHYImpl() {
        super();
        javaPojoGenerators = new ArrayList<>();
        javaMapperGenerators = new ArrayList<>();
        javaServiceGenerators = new ArrayList<>();
        javaVoGenerators = new ArrayList<>();
        javaRequestGenerators = new ArrayList<>();
        javaHelperGenerators = new ArrayList<>();
        javaControllerGenerators = new ArrayList<>();
        javaConstantGenerators = new ArrayList<>();
    }

    @Override
    public void calculateGenerators(List<String> warnings, ProgressCallback progressCallback) {
        //pojo
        calculateJavaPojoGenerators(warnings, progressCallback);

        //mapper
        AbstractJavaClientGenerator javaClientGenerator = calculateJavaMapperGenerators(warnings, progressCallback);

        //xml mapper
        calculateXmlMapperGenerator(javaClientGenerator, warnings, progressCallback);

        //service
        createJavaServiceGenerator(warnings, progressCallback);

        //vo
        calculateJavaVoGenerators(warnings, progressCallback);

        //request
        calculateJavaRequestGenerators(warnings, progressCallback);

        //helper
        calculateJavaHelperGenerators(warnings, progressCallback);

        //controller
        calculateJavaControllerGenerators(warnings, progressCallback);

        //constant
        calculateJavaConstantGenerators(warnings, progressCallback);


    }

    @Override
    public List<GeneratedJavaFile> getGeneratedJavaFiles() {
        List<GeneratedJavaFile> answer = new ArrayList<GeneratedJavaFile>();

        for (AbstractJavaGenerator javaGenerator : javaPojoGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_PO).getTargetObject(), null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : javaVoGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_VO).getTargetObject(), null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : javaMapperGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator .getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_MAPPER).getTargetObject(),null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : javaServiceGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_SERVICE).getTargetObject(),null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : javaRequestGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_REQUEST).getTargetObject(),null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : javaHelperGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_HELPER).getTargetObject(),null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : javaControllerGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_CONTROLLER).getTargetObject(),null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        for (AbstractJavaGenerator javaGenerator : javaConstantGenerators) {
            List<CompilationUnit> compilationUnits = javaGenerator.getCompilationUnits();
            for (CompilationUnit compilationUnit : compilationUnits) {
                GeneratedJavaFile gjf = new GeneratedJavaFile(compilationUnit,context.getConfiguration(ConfigurationConstant.CONFIGURATION_CONSTANT).getTargetObject(),null,context.getJavaFormatter());
                answer.add(gjf);
            }
        }

        return answer;
    }

    @Override
    public List<GeneratedXmlFile> getGeneratedXmlFiles() {
        List<GeneratedXmlFile> answer = new ArrayList<GeneratedXmlFile>();

        if (xmlMapperGenerator != null) {
            Document document = xmlMapperGenerator.getDocument();
            GeneratedXmlFile gxf = new GeneratedXmlFile(document,getMyBatis3XmlMapperFileName(), getMyBatis3XmlMapperPackage(),context.getConfiguration(ConfigurationConstant.CONFIGURATION_SQLMAP).getTargetObject(),false, context.getXmlFormatter());
            if (context.getPlugins().sqlMapGenerated(gxf, this)) {
                answer.add(gxf);
            }
        }

        return answer;
    }

    @Override
    public boolean isJava5Targeted() {
        return true;
    }

    @Override
    public int getGenerationSteps() {
        return javaPojoGenerators.size()
                + javaMapperGenerators.size()
                + javaServiceGenerators.size()
                + javaVoGenerators.size()
                + (xmlMapperGenerator == null ? 0 : 1);
    }

    @Override
    public boolean requiresXMLGenerator() {
        AbstractJavaClientGenerator javaClientGenerator = createJavaMapperGenerator();
        if (javaClientGenerator == null) {
            return false;
        } else {
            return javaClientGenerator.requiresXMLGenerator();
        }
    }

    protected void calculateXmlMapperGenerator(AbstractJavaClientGenerator javaClientGenerator, List<String> warnings, ProgressCallback progressCallback) {
        if (javaClientGenerator == null) {
            if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_SQLMAP) != null) {
                xmlMapperGenerator = new XMLMapperGenerator();
            }
        } else {
            xmlMapperGenerator = javaClientGenerator.getMatchedXMLGenerator();
        }

        initializeAbstractGenerator(xmlMapperGenerator, warnings, progressCallback);
    }

    protected AbstractJavaClientGenerator calculateJavaMapperGenerators(List<String> warnings, ProgressCallback progressCallback) {
        if (!rules.generateJavaClient()) {
            return null;
        }

        AbstractJavaClientGenerator javaGenerator = createJavaMapperGenerator();
        if (javaGenerator == null) {
            return null;
        }

        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaMapperGenerators.add(javaGenerator);

        return javaGenerator;
    }

    protected AbstractJavaClientGenerator createJavaMapperGenerator() {
        if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_MAPPER) == null) {
            return null;
        }
        AbstractJavaClientGenerator javaGenerator = new JavaMapperGenerator();
        return javaGenerator;
    }

    protected void createJavaServiceGenerator(List<String> warnings, ProgressCallback progressCallback) {
        if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_SERVICE) == null) {
            return;
        }
        AbstractJavaGenerator javaGenerator = new JavaServiceGenerator();
        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaServiceGenerators.add(javaGenerator);
    }

    protected void calculateJavaPojoGenerators(List<String> warnings, ProgressCallback progressCallback) {
        AbstractJavaGenerator javaGenerator = new JavaPojoGenerator();
        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaPojoGenerators.add(javaGenerator);

    }

    protected void calculateJavaVoGenerators(List<String> warnings, ProgressCallback progressCallback) {
        if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_VO) == null) {
            return;
        }
        AbstractJavaGenerator javaGenerator = new JavaVoGenerator();
        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaVoGenerators.add(javaGenerator);
    }

    protected void initializeAbstractGenerator(AbstractGenerator abstractGenerator, List<String> warnings, ProgressCallback progressCallback) {
        if (abstractGenerator == null) {
            return;
        }
        abstractGenerator.setContext(context);
        abstractGenerator.setIntrospectedTable(this);
        abstractGenerator.setProgressCallback(progressCallback);
        abstractGenerator.setWarnings(warnings);
    }

    private void calculateJavaControllerGenerators(List<String> warnings, ProgressCallback progressCallback) {
        if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_CONTROLLER) == null) {
            return;
        }
        AbstractJavaGenerator javaGenerator = new JavaControllerGenerator();
        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaControllerGenerators.add(javaGenerator);
    }

    private void calculateJavaHelperGenerators(List<String> warnings, ProgressCallback progressCallback) {
        if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_HELPER) == null) {
            return;
        }
        AbstractJavaGenerator javaGenerator = new JavaHelperGenerator();
        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaHelperGenerators.add(javaGenerator);
    }

    private void calculateJavaRequestGenerators(List<String> warnings, ProgressCallback progressCallback) {
        if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_REQUEST) == null) {
            return;
        }
        AbstractJavaGenerator javaGenerator = new JavaRequestGenerator();
        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaRequestGenerators.add(javaGenerator);
    }

    private void calculateJavaConstantGenerators(List<String> warnings, ProgressCallback progressCallback) {
        if (context.getConfiguration(ConfigurationConstant.CONFIGURATION_CONSTANT) == null) {
            return;
        }
        AbstractJavaGenerator javaGenerator = new JavaConstantGenerator();
        initializeAbstractGenerator(javaGenerator, warnings, progressCallback);
        javaConstantGenerators.add(javaGenerator);
    }

}
